#include<stdio.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
#include "../include/meta.h"
#include "../include/vfs_errorcodes.h"
void insertIntoTree_mount(char strin[100], node *root,int index){
	//int index;
	char result[100];
	node *prev= (node *) malloc(sizeof(node));
	node* temp=(node*) malloc(sizeof(node));
	//printf("nary0\n");
	//splitting full path at '/'
	char *token;
	token=strtok(strin,"/");;
//printf("nary01\n");
	if(strcmp(root->data,token)!=0)
		{printf("Wrong path\n");
		 return;
		}
		//printf("nary02%s\n",token);

	while(token!=NULL)
	{
	if(root==NULL)
		{

		temp=(node *)insertNode(token,index);
		prev->lchild=temp;
		temp->parent = prev;
		 prev=prev->lchild;
		 root=prev->lchild;

		}


	else if(strcmp(root->data,token)==0) // match
		{
			prev=root;

		 root=root->lchild;
		}
	else if(strcmp(root->data,token)!=0) // no match
		{
		while((root->rchild!=NULL)&&(strcmp(root->data,token)!=0))
			root=root->rchild;
		 if(strcmp(root->data,token)==0)
		 {
		  prev = root;
		  root=root->lchild;
		 }
		 else
		 {

		  temp=(node *)insertNode(token,index);

		  root->rchild=temp;
		  temp->parent = root->parent;

		  prev=root->rchild;
		  root=prev->lchild;
		 }
		}
	token=strtok(NULL,"/");

	}
	//return temp;
}

char* mount_vfs(char label[])
{
	char result[100];
	//printf("label is : %s\n",label);
	//displayTree(root);
	if(strcmp(label,"")==0)
	{
		strcpy(result,"mountvfs_FAILURE ");
				strcat(result,ERR_VFS_MOUNT_00);
				sprintf(str, "%s",result);
				return str;
		 //VFS_INSUFFICIENT_ARGUMENTS
	}
	
	if(root!=NULL)
	{
		strcpy(result,"mountvfs_FAILURE ");
				strcat(result,ERR_VFS_MOUNT_03);
				sprintf(str, "%s",result);
				return str;
		//vfs_already_mounted
	}
	long a;
	int i=0;
	char vfs_label[30];

	strcat(label,".dat");
	strcpy(mounted_vfs,label);
	FILE *fp = fopen(label, "rb+");

	if(fp==0)
	{
		strcpy(result,"mountvfs_FAILURE ");
				strcat(result,ERR_VFS_MOUNT_01);
				sprintf(str, "%s",result);
				return str;
		//return ERR_VFS_MOUNT_01;//DATA_FILE_NOT_FOUND
	}
		else
		{

	main_header_var = (main_header *)malloc(sizeof(main_header));
	fread(main_header_var,sizeof(main_header),1,fp);
	//after reading main header,also populate other values such as header size,no of used file descriptors etc.
//the address of block i would be headersize+(i*blocksize)

	strcpy(vfs_label,main_header_var->label);
	size = main_header_var->max_no_file_descriptors;
	bl_size = main_header_var->max_no_blocks;
	int nfds= main_header_var->no_used_file_descriptors;

	root = (node *)createTree();
	bstroot=(bstnode *)bst_insert(bstroot,"/home/",0);

	char vfs_label_filename[35];
	strcpy(vfs_label_filename,vfs_label);
	strcat(vfs_label_filename,".dat");
	int xy = strcmp(vfs_label_filename,label);
		//printf("the filesyslabel and given label are %s , %s,%d",vfs_label_filename,label,xy);
		
	if(nfds == 0 || xy!=0)
	{
		strcpy(result,"mountvfs_FAILURE ");
				strcat(result,ERR_VFS_MOUNT_02);
				sprintf(str, "%s",result);
				return str;
		//return ERR_VFS_MOUNT_02; //CANNOT_READ_FROM_FILE
	}

	fd =(file_descriptor *)malloc(size*sizeof(file_descriptor));

	fl = (freelist *)malloc(size*sizeof(freelist));


	bl = (blocklist *)malloc(size*sizeof(blocklist));
	char name[150] ;


	int j;
fread(fd,size*sizeof(file_descriptor),1,fp);

	/*for(j=0;j<size;j++)
	{
	fread(&fd[j],sizeof(file_descriptor),1,fp);
	}*/


		int x= ftell(fp);
	//printf("all fds read%d\n",x);
	fread(fl,size*sizeof(freelist),1,fp);
	fread(bl,(size/1.3)*sizeof(blocklist),1,fp);
/*	for(j=0;j<size;j++)
	{
	fread(&fl[j],sizeof(freelist),1,fp);
	}*/
	int q;

	for(q=0;q<=61;q++)
	{
		//hash_table[i] = (struct list *)malloc(sizeof(struct list));
		hash_table[q] = NULL;
	}

	int hashvalue=0;
	size = main_header_var->max_no_file_descriptors;
	//printf("\n%d\n",size);

	i=1;
	while(i<size)
	{

	if(fl[i].a == 1)
		{
			//printf("%d",i);
			strcpy(name,fd[i].location_path);


			//nary insert
				//printf("file_path: %s file_type: %s\n",fd[i].location_path,fd[i].file_type);
			if(strcmp(fd[i].file_type,"folder")==0)
			{
			insertIntoTree_mount(name,root,i);
			}
			else if(strcmp(fd[i].file_type,"file")==0)
			{

			insertIntoTree_mount(name,root,i);}

		//printf("%s,%s",fd[i].file_name,fd[i].location_path);
		hashvalue = hash(fd[i].file_name);

	insert_into_list(hashvalue,fd[i].file_name,fd[i].location_path);

			//bst insert
           bstroot=(bstnode *)bst_insert(bstroot,fd[i].location_path,i);
			//printf("root is %s",bstroot->data);
		}
		i++;
	}
	//display();
//printf("header size: %d\n",main_header_var->headersize);
//displayTree(root);
	//fl[1].a = 0;
	fclose(fp);

}

return "mountvfs_SUCCESS";
}


